#include "Output.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

// 继电器通道配置数组
Relay_Channel_t RelayChannels[] = {
    [RELAY_ALARM_1]  = {GPIOC, GPIO_Pin_0, RELAY_ACTIVE_HIGH},   // 报警继电器1
    [RELAY_ALARM_2]  = {GPIOC, GPIO_Pin_1, RELAY_ACTIVE_HIGH},   // 报警继电器2
    [BATTERY_CHARGE] = {GPIOC, GPIO_Pin_5, RELAY_ACTIVE_HIGH},   // 电池充电控制继电器
};
// 获取继电器通道数量
#define RELAY_COUNT (sizeof(RelayChannels) / sizeof(Relay_Channel_t))

// 继电器初始化函数
void Relay_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 初始化所有继电器通道
    for (uint8_t i = 0; i < RELAY_COUNT; i++) {
        Relay_Channel_t* channel = &RelayChannels[i];

        // 使能对应GPIO端口的时钟
        if (channel->GPIOx == GPIOA) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        } else if (channel->GPIOx == GPIOB) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        } else if (channel->GPIOx == GPIOC) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        } else if (channel->GPIOx == GPIOD) {
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
        }

        // 配置GPIO为推挽输出
        GPIO_InitStructure.GPIO_Pin   = channel->GPIO_Pin;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(channel->GPIOx, &GPIO_InitStructure);

        // 初始状态：关闭继电器
        if (channel->activeLevel == RELAY_ACTIVE_HIGH) {
            GPIO_ResetBits(channel->GPIOx, channel->GPIO_Pin);
        } else {
            GPIO_SetBits(channel->GPIOx, channel->GPIO_Pin);
        }
    }
}

// 继电器控制函数
void Output_Control(uint8_t channel, uint8_t state) {
    if (channel >= RELAY_COUNT) {
        return;   // 通道检查
    }
    Relay_Channel_t* relay = &RelayChannels[channel];

    // 控制对应引脚
    if ((relay->activeLevel == RELAY_ACTIVE_HIGH && state == RELAY_STATE_ON) ||
        (relay->activeLevel == RELAY_ACTIVE_LOW && state == RELAY_STATE_OFF)) {
        GPIO_SetBits(relay->GPIOx, relay->GPIO_Pin);
    } else {
        GPIO_ResetBits(relay->GPIOx, relay->GPIO_Pin);
    }
}
